package com.sc.nft.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.ActivityCouponsDao;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.vo.ActivityCouponsBatchIssueVO;
import com.sc.nft.entity.vo.ActivityCouponsListVO;
import com.sc.nft.entity.vo.ActivityCouponsProductVO;
import com.sc.nft.entity.vo.EditActivityCouponsVO;
import com.sc.nft.entity.vo.mall.CategoryProductPageVO;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageResult;
import com.sc.nft.util.Beans;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 优惠券活动服务实现
 *
 * @author liGen
 * @version 1.0
 * @date 2023/12/5 4:40 下午
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ActivityCouponsServiceImpl implements ActivityCouponsService {

    private final ActivityCouponsDao activityCouponsDao;
    private final MallActivityService mallActivityService;
    @Autowired
    ActivityCouponsUserService activityCouponsUserService;
    private final UserInfoService userInfoService;
    private final UserCouponsService userCouponsService;
    private final MallMemberService mallMemberService;
    private final MallMemberEquityService mallMemberEquityService;
    private final MallMemberEquityTargetService mallMemberEquityTargetService;
    private final MallMemberEquityTemplateService mallMemberEquityTemplateService;

    /**
     * 创建优惠券活动
     *
     * @param vo
     * @return
     */
    @Override
    public void create(EditActivityCouponsVO vo) {
        vo.check();
        ActivityCoupons activityCoupons = new ActivityCoupons();
        BeanUtils.copyProperties(vo, activityCoupons);
        activityCoupons.setStatus(CouponsStatusEnum.STATUS_DISABLE);
        activityCoupons.setSort(1);
        activityCoupons.setProductIds(JSON.toJSONString(vo.getProductIdList()));
        activityCoupons.insert();
    }

    /**
     * 修改优惠券活动
     *
     * @param vo
     * @return
     */
    @Override
    public void update(EditActivityCouponsVO vo) {
        if (Objects.nonNull(vo.getId())) {
            vo.check();
            ActivityCoupons activityCoupons = getById(vo.getId());
            if (activityCoupons.getStatus() == CouponsStatusEnum.STATUS_NORMAL) {
                throw new GlobalRunTimeException("优惠券活动已上架无法编辑！");
            }
            Beans.copyPropertiesIgnoreNull(vo, activityCoupons);
            activityCoupons.setProductIds(JSON.toJSONString(vo.getProductIdList()));
            activityCoupons.updateById();
        }
    }

    /**
     * 优惠券活动上架
     *
     * @param id
     */
    @Override
    public void enable(Long id) {
        ActivityCoupons activityCoupons = getById(id);
        activityCouponsDao.updateStatus(activityCoupons.getId(), CouponsStatusEnum.STATUS_NORMAL);
    }

    /**
     * 优惠券活动下架
     *
     * @param id
     */
    @Override
    public void disable(Long id) {
        ActivityCoupons activityCoupons = getById(id);
        activityCouponsDao.updateStatus(activityCoupons.getId(), CouponsStatusEnum.STATUS_DISABLE);
    }

    /**
     * 修改优惠券排序
     *
     * @param id
     * @param sort
     */
    @Override
    public void updateSort(Long id, Integer sort) {
        ActivityCoupons activityCoupons = getById(id);
        activityCouponsDao.updateSort(activityCoupons.getId(), sort);
    }

    /**
     * 优惠券列表
     *
     * @param activityCouponsListVO
     * @return
     */
    @Override
    public Page<ActivityCouponsDTO> getAdminActivityCouponsDTOPage(ActivityCouponsListVO activityCouponsListVO) {
        Page<ActivityCouponsDTO> adminPageActivityCouponsDTOPage = activityCouponsDao.getAdminPageActivityCouponsDTO(activityCouponsListVO.getPageNo(), activityCouponsListVO.getPageSize(), activityCouponsListVO.getTitle(), activityCouponsListVO.getCouponsListStatus());
        for (ActivityCouponsDTO activityCouponsDTO : adminPageActivityCouponsDTOPage.getRecords()) {
            if (activityCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_DISABLE || DateTime.now().after(activityCouponsDTO.getEndTime())) {
                activityCouponsDTO.setCouponsListStatus(CouponsListStatusEnum.FINISHED);
            }
            if (activityCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_NORMAL && DateTime.now().before(activityCouponsDTO.getStartTime())) {
                activityCouponsDTO.setCouponsListStatus(CouponsListStatusEnum.NOT_STARTED);
            }
            if (activityCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_NORMAL && DateTime.now().after(activityCouponsDTO.getStartTime()) && DateTime.now().before(activityCouponsDTO.getEndTime())) {
                activityCouponsDTO.setCouponsListStatus(CouponsListStatusEnum.UNDERWAY);
            }
            if (activityCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_NORMAL) {
                activityCouponsDTO.setAdminStatus(true);
            } else {
                activityCouponsDTO.setAdminStatus(false);
            }
        }
        return adminPageActivityCouponsDTOPage;
    }

    /**
     * 用户端优惠券列表
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public Page<ActivityCouponsDTO> getMallActivityCouponsDTOPage(Integer pageNo, Integer pageSize, UserInfo userInfo, Long productId) {
        Page<ActivityCouponsDTO> mallPageActivityCouponsDTO = activityCouponsDao.getMallPageActivityCouponsDTO(pageNo, pageSize, productId);
        ActivityCouponsProductVO activityCouponsProductVO = new ActivityCouponsProductVO();
        activityCouponsProductVO.setPageNo(1);
        activityCouponsProductVO.setPageSize(3);
        for (ActivityCouponsDTO activityCouponsDTO : mallPageActivityCouponsDTO.getRecords()) {
            activityCouponsProductVO.setCouponsId(activityCouponsDTO.getId());
            Page<ActivityCouponsProductDTO> activityCouponsProductDTOPage = getActivityCouponsProductDTOPage(activityCouponsProductVO);
            List<ActivityCouponsProductDTO> activityCouponsProductDTOList = activityCouponsProductDTOPage.getRecords();
            activityCouponsDTO.setActivityCouponsProductDTOS(activityCouponsProductDTOList);
            ReceiveVerificationDTO receiveVerificationDTO = activityCouponsUserService.receiveVerification(activityCouponsDTO.getId(), activityCouponsDTO.getStartTime(), activityCouponsDTO.getEndTime(), userInfo, null, null);
            if (ReceiveStatusEnum.CAN_PICK == receiveVerificationDTO.getReceiveStatusEnum()) {
                activityCouponsDTO.setIsCanReceive(true);
                activityCouponsDTO.setIsReceive(false);
            } else {
                if (ReceiveStatusEnum.PICKED == receiveVerificationDTO.getReceiveStatusEnum()) {
                    activityCouponsDTO.setIsReceive(true);
                }
                activityCouponsDTO.setIsCanReceive(false);
            }
        }
        return mallPageActivityCouponsDTO;
    }

    /**
     * 会员专区用户端优惠券列表
     *
     * @param pageNo
     * @param pageSize
     * @param userInfo
     * @param memberId
     * @return
     */
    @Override
    public Page<ActivityCouponsDTO> getMallMemberActivityCouponsDTOPage(Integer pageNo, Integer pageSize, UserInfo userInfo, Long memberId, Long memberEquityTemplateId) {
        // 获取用户会员
        List<UserMallMemberDTO> userMallMemberPageDTOList = mallMemberService.getUserMallMemberPageDTO(userInfo);
        UserMallMemberDTO userMallMember = userMallMemberPageDTOList.stream().filter(userMallMemberDTO -> userMallMemberDTO.getId().equals(memberId)).findFirst().orElse(null);
        Assert.notNull(userMallMember, () -> new GlobalRunTimeException("未拥有会员,请获取会员"));
        // 判断是否拥有该权益
        MallMemberEquityPageDTO memberEquityPageDTO = userMallMember.getMallMemberEquityPageDTOList().stream().filter(mallMemberEquityPageDTO -> mallMemberEquityPageDTO.getMallMemberEquityTemplateId().equals(memberEquityTemplateId) && mallMemberEquityPageDTO.getIsHold()).findFirst().orElse(null);
        Assert.notNull(memberEquityPageDTO, () -> new GlobalRunTimeException("无法享有该权益"));
        // 获取会员权益
        MallMemberEquity mallMemberEquity = mallMemberEquityService.get(memberEquityTemplateId, memberId);
        // 是否是优惠券权益
        Assert.isTrue(mallMemberEquity.getEquityType().equals(EquityTypeEnum.DISCOUNT_COUPON), () -> new GlobalRunTimeException("无法享有该权益"));
        // 获取会员权益对应福利
        List<MallMemberEquityTarget> mallMemberEquityTargetList = mallMemberEquityTargetService.getListById(mallMemberEquity.getId());
        List<Long> activityCouponIds = mallMemberEquityTargetList.stream().map(mallMemberEquityTarget -> mallMemberEquityTarget.getTargetId()).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(activityCouponIds)){
           activityCouponIds.add(0L);
        }
        // 获取优惠券信息
        Page<ActivityCouponsDTO> mallPageActivityCouponsDTO = activityCouponsDao.getMallMemberActivityCouponsDTO(pageNo, pageSize, activityCouponIds);
        // 获取会员权益模版信息
        MallMemberEquityTemplate mallMemberEquityTemplate = mallMemberEquityTemplateService.getById(memberEquityTemplateId);
        for (ActivityCouponsDTO activityCouponsDTO : mallPageActivityCouponsDTO.getRecords()) {
            ReceiveVerificationDTO receiveVerificationDTO = activityCouponsUserService.receiveVerification(activityCouponsDTO.getId(), activityCouponsDTO.getStartTime(), activityCouponsDTO.getEndTime(), userInfo, mallMemberEquity, mallMemberEquityTemplate);
            activityCouponsDTO.setLastClaimTime(receiveVerificationDTO.getLastClaimTime());
            activityCouponsDTO.setRemainingNumberOfReceive(receiveVerificationDTO.getRemainingNumberOfReceive());
            if (ReceiveStatusEnum.CAN_PICK == receiveVerificationDTO.getReceiveStatusEnum()) {
                activityCouponsDTO.setIsCanReceive(true);
                activityCouponsDTO.setIsReceive(false);
            } else {
                if (ReceiveStatusEnum.PICKED == receiveVerificationDTO.getReceiveStatusEnum()) {
                    activityCouponsDTO.setIsReceive(true);
                }else {
                    activityCouponsDTO.setIsReceive(false);
                }
                activityCouponsDTO.setIsCanReceive(false);
            }
        }
        return mallPageActivityCouponsDTO;
    }

    /**
     * 获取活动优惠券
     *
     * @param id
     * @return
     */
    @Override
    public ActivityCoupons getById(Long id) {
        ActivityCoupons activityCoupons = activityCouponsDao.getById(id);
        Assert.notNull(activityCoupons, () -> new GlobalRunTimeException(ErrorCode.COUPONS_ACTIVITY_NOT_EXIST));
        return activityCoupons;
    }

    /**
     * 获取活动优惠券
     *
     * @param id
     * @return
     */
    @Override
    public ActivityCouponsDetailDTO getActivityCouponsDetailDTOById(Long id) {
        ActivityCoupons activityCoupons = getById(id);
        return ActivityCouponsDetailDTO.build(activityCoupons);
    }

    /**
     * 获取优惠券下的可用商品
     *
     * @param activityCouponsProductVO
     * @return
     */
    @Override
    public Page<ActivityCouponsProductDTO> getActivityCouponsProductDTOPage(ActivityCouponsProductVO activityCouponsProductVO) {
        ActivityCoupons activityCoupons = getById(activityCouponsProductVO.getCouponsId());
        String productIds = activityCoupons.getProductIds();
        if (StringUtils.isEmpty(productIds)) {
            return null;
        }
        List<Long> ids = JSONArray.parseArray(productIds, Long.class);
        Page<ActivityCouponsProductDTO> activityCouponsProductDTOPage = mallActivityService.getActivityCouponsProductDTOPage(ids, new Page(activityCouponsProductVO.getPageNo(), activityCouponsProductVO.getPageSize()),MallActivityStatusEnum.AVAILABLE.getCode());
        for (ActivityCouponsProductDTO record : activityCouponsProductDTOPage.getRecords()) {
            if (record.getSpecsCount() > 1) {
                record.setSalesPrice(record.getSalesPrice());
            }
            if (StrUtil.isNotBlank(record.getCoverImage())) {
                record.setCoverImage(StrUtil.split(record.getCoverImage(), ",").get(0));
            }
        }
        return activityCouponsProductDTOPage;
    }

    /**
     * 获取优惠券下的可用商品
     *
     * @param activityCouponsProductVO
     * @return
     */
    @Override
    public List<ActivityCouponsProductDTO> getActivityCouponsProductDTOList(ActivityCouponsProductVO activityCouponsProductVO) {
        ActivityCoupons activityCoupons = getById(activityCouponsProductVO.getCouponsId());
        String productIds = activityCoupons.getProductIds();
        if (StringUtils.isEmpty(productIds)) {
            return null;
        }
        List<Long> ids = JSONArray.parseArray(productIds, Long.class);
        List<ActivityCouponsProductDTO> activityCouponsProductDTOList = mallActivityService.getActivityCouponsProductDTOList(ids);
        return activityCouponsProductDTOList;
    }

    /**
     * 空投优惠券
     *
     * @param activityCouponsBatchIssueVO
     * @return
     */
    @Override
    public void batchIssueCoupons(ActivityCouponsBatchIssueVO activityCouponsBatchIssueVO) {
        ActivityCoupons activityCoupons = getById(activityCouponsBatchIssueVO.getCouponsId());
        Assert.notNull(activityCoupons, () -> new GlobalRunTimeException(ErrorCode.COUPONS_ACTIVITY_NOT_EXIST));
        Assert.isFalse(new Date().after(activityCoupons.getEndTime()),()-> new GlobalRunTimeException(ErrorCode.COUPONS_ACTIVITY_DATE_EXPIRE));
        List<UserInfo> userInfoList = userInfoService.getByIdList(activityCouponsBatchIssueVO.getUserIdList());
        Assert.notEmpty(userInfoList, () -> new GlobalRunTimeException(ErrorCode.THE_TARGET_USER_DOES_NOT_EXIST));
        userInfoList.forEach(e -> {
            UserCoupons userCoupons = userCouponsService.receive(activityCoupons, e);
            activityCouponsUserService.create(activityCoupons, e, userCoupons,null);
        });
    }

    /**
     * 批量空投优惠券选择优惠券列表
     *
     * @param activityCouponsListVO
     * @return
     */
    @Override
    public Page<ActivityBatchIssueCouponsDTO> batchIssuePage(ActivityCouponsListVO activityCouponsListVO) {
        Page<ActivityBatchIssueCouponsDTO> batchIssueCouponsDTOPage = activityCouponsDao.batchIssuePage(activityCouponsListVO.getPageNo(), activityCouponsListVO.getPageSize(), activityCouponsListVO.getTitle());
        for (ActivityBatchIssueCouponsDTO batchIssueCouponsDTO : batchIssueCouponsDTOPage.getRecords()) {
            if (batchIssueCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_DISABLE || DateTime.now().after(batchIssueCouponsDTO.getEndTime())) {
                batchIssueCouponsDTO.setCouponsListStatus(CouponsListStatusEnum.FINISHED);
            }
            if (batchIssueCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_NORMAL && DateTime.now().before(batchIssueCouponsDTO.getStartTime())) {
                batchIssueCouponsDTO.setCouponsListStatus(CouponsListStatusEnum.NOT_STARTED);
            }
            if (batchIssueCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_NORMAL && DateTime.now().after(batchIssueCouponsDTO.getStartTime()) && DateTime.now().before(batchIssueCouponsDTO.getEndTime())) {
                batchIssueCouponsDTO.setCouponsListStatus(CouponsListStatusEnum.UNDERWAY);
            }
            if (batchIssueCouponsDTO.getStatus() == CouponsStatusEnum.STATUS_NORMAL) {
                batchIssueCouponsDTO.setAdminStatus(true);
            } else {
                batchIssueCouponsDTO.setAdminStatus(false);
            }
        }
        return batchIssueCouponsDTOPage;
    }
}
